package io.esirong.base;

import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toolbar;

import org.greenrobot.eventbus.EventBus;

import androidx.annotation.IdRes;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import butterknife.ButterKnife;
import butterknife.Unbinder;

/**
 * 基础Fragment；继承Android 平台 Fragment
 *
 * @author 黄嵘才(HuangRc)
 */
public abstract class BaseFragment extends LifecycleFragment {
    /**
     * 日志标签，其值是实例类的类名称
     */
    private final String TAG = "BaseFragment";

    /**
     * 是否第一次可见
     */
    protected boolean mIsFirstVisible = true;
    /**
     * 当前可见状态
     */
    protected boolean currentVisibleState = false;

    private Toolbar mToolbar;

    private Unbinder unBinder;

    /**
     * 初始化UI的View
     *
     * @param view 已创建好的View
     */
    protected abstract void initView(View view);


    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        return super.onCreateView(inflater, container, savedInstanceState);
    }

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        if (!isHidden() && getUserVisibleHint()) {
            // 可见状态,进行事件分发
            dispatchUserVisibleHint(true);
        }
        initView(view);
        setupToolbar(view);
        unBinder = ButterKnife.bind(this, view);
        if (regEvent()) {
            EventBus.getDefault().register(this);
        }
    }

    @Override
    public void onResume() {
        super.onResume();
        // onResume并不代表fragment可见
        // 如果是在viewpager里，就需要判断getUserVisibleHint，不在viewpager时，getUserVisibleHint默认为true
        // 如果是其它情况，就通过isHidden判断，因为show/hide时会改变isHidden的状态
        // 所以，只有当fragment原来是可见状态时，进入onResume就回调onVisible
        // 如果不是第一次可见
        if (!mIsFirstVisible) {
            if (getUserVisibleHint() && !isHidden()) {
                onVisible();
            }
        }

    }

    /**
     * 只有当当前页面由可见状态转变到不可见状态时才需要调用 dispatchUserVisibleHint currentVisibleState &&
     * getUserVisibleHint() 能够限定是当前可见的 Fragment 当前 Fragment 包含子 Fragment 的时候
     * dispatchUserVisibleHint 内部本身就会通知子 Fragment 不可见 子 fragment 走到这里的时候自身又会调用一遍
     */
    @Override
    public void onPause() {
        super.onPause();
        if (currentVisibleState && getUserVisibleHint()) {
            dispatchUserVisibleHint(false);
        }
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        if (unBinder != null) {
            unBinder.unbind();
        }
        if (regEvent()) {
            EventBus.getDefault().unregister(this);
        }
    }

    /**
     * 需要接收事件(默认false) 子类可重写该方法 并返回true
     */
    protected boolean regEvent() {
        return false;
    }

    /**
     * 修改Fragment的可见性 setUserVisibleHint 被调用有两种情况：
     * 1）在切换tab的时候，会先于所有fragment的其他生命周期，先调用这个函数，可以看log 2)
     * 对于之前已经调用过setUserVisibleHint方法的fragment后，让fragment从可见到不可见之间状态的变化
     */
    @Override
    public void setUserVisibleHint(boolean isVisibleToUser) {
        super.setUserVisibleHint(isVisibleToUser);

    }

    @Override
    public void onHiddenChanged(boolean hidden) {
        super.onHiddenChanged(hidden);
        // 这里的可见返回为false
        dispatchUserVisibleHint(!hidden);
    }

    /**
     * 显示（页显在用户面前时回调此法）
     */
    protected void onVisible() {
        dispatchUserVisibleHint(true);
    }

    /**
     * 初始化显示
     *
     * @param initOn 是不是第一次显示 true,是；false,不是
     */
    protected void onVisibleInit(boolean initOn) {

    }

    private void dispatchUserVisibleHint(boolean isVisible) {
        // 为了代码严谨,如果当前状态与需要设置的状态本来就一致了,就不处理了
        if (currentVisibleState == isVisible) {
            return;
        }

        currentVisibleState = isVisible;

        if (isVisible) {
            if (mIsFirstVisible) {
                mIsFirstVisible = false;
                // 第一次可见,进行全局初始化
                onVisibleInit(true);
            }
            onFragmentResume();
            // 分发事件给内嵌的Fragment
            dispatchChildVisibleState(true);
        } else {
            onFragmentPause();
            dispatchChildVisibleState(false);
        }
    }

    protected void dispatchChildVisibleState(boolean isVisible) {

    }

    protected void onFragmentResume() {

    }

    protected void onFragmentPause() {

    }

    private boolean isParentInvisible() {
        Fragment parentFragment = getParentFragment();
        return true;
    }

    /**
     * 初始化Toolbar
     */
    private void setupToolbar(View view) {
        if (mToolbar == null) {
            //findView
            mToolbar = view.findViewById(R.id.toolbar);
            if (mToolbar != null) {
                //setupView
            }
        }
    }

    /**
     * 返回设置的Toolbar
     *
     * @return Toolbar
     */
    public Toolbar getToolbar() {
        return mToolbar;
    }

    @SuppressWarnings("unchecked")
    public <T extends View> T findViewById(@IdRes int viewId) {
        View view = null;
        if (getView() != null) {
            view = getView().findViewById(viewId);
        }
        return (T) view;
    }

}
